from typing import Optional, List
from sqlmodel import Session, Field, select
# from crud.system import menu
from dependencies import engine, SessionDep
import models
import common
# from crud import org
import time
import datetime
import random
import hashlib

id_to_name_rule = [
    {
        "field": "create_id",
        "name": "creator",
        "model": models.SystemUser,
    },
    {
        "field": "update_id",
        "name": "updater",
        "model": models.SystemUser,
    },
    {
        "field": "org_id",
        "name": "org_name",
        "model": models.SystemOrg,
    },
]

"""将创建人和更新人的ID转换为姓名，并将组织机构id转换为组织机构名称

Keyword arguments:
items -- 转化的数据
rules -- 转换规则 (default id_to_name_rule)
Return: result -- 转换后的结果
"""


def convert_id_to_name(items: list,
                       rules: list = id_to_name_rule,
                       session: SessionDep = Session(engine)):
    # 初始化结果列表
    result = []

    # 将创建人和更新人的ID转换为姓名
    if items:
        for i in items:
            # 将i转化成字典
            i = dict(i)
            # 将ID转换为名称
            for rule in rules:
                if rule["field"] in i:
                    i[rule["name"]] = session.get(
                        rule["model"], i[rule["field"]]).name if i[rule["field"]] else None

            # 添加到结果列表
            result.append(i)
    return result


"""将查询出来的结果组装成树状结构

Keyword arguments:
items -- 查询结果
parent_id: 父级id (default None)
depth: 递归深度 (default 0)
Return: tree -- 树状结构
"""


def build_tree_recursive(items, parent_id=None, depth=0):
    tree = []
    for item in items:
        # 将item转化成字典
        item = dict(item)
        # 如果当前节点的parent_id等于传入的parent_id，则将其添加到树中
        if item["parent_id"] == parent_id and depth <= 10:
            # 递归构建当前节点的子树
            children = build_tree_recursive(
                items, parent_id=item["id"], depth=depth + 1)
            if children:
                item["children"] = children
            tree.append(item)
    return tree


"""将树状结构的数据转化成列表,列表中不包含子节点

Keyword arguments:
items -- 树状结构
depth: 递归深度 (default 0)
Return: result -- 列表
"""


def build_tree_list(items: List, depth=0):
    result = []
    for item in items:
        if depth <= 10:
            result.append(item)
            if "children" in item and item["children"]:
                result.extend(build_tree_list(item["children"], depth + 1))

    # 将结果中的children键删除
    for item in result:
        item.pop("children", None)
    return result


def flatten_options(items: List, depth=0):
    result = []
    for item in items:
        if depth <= 10:
            result.append(item)
            if item.children:
                result.extend(flatten_options(item.children, depth + 1))
    return result


"""获取当前节点的所有子节点id

Keyword arguments:
items -- 查询结果
parent_id: 父级id (default None)
depth: 递归深度 (default 0)
Return: ids -- 当前节点及其子节点id
"""


def get_node_ids(items, parent_id=None, depth=0):
    if parent_id not in [None, 0]:
        ids = [parent_id]
        for item in items:
            if item.parent_id == parent_id and depth <= 10:
                ids.extend(get_node_ids(
                    items, parent_id=item.id, depth=depth + 1))
    else:
        ids = [i.id for i in items]
    return ids


"""数据操作权限校验

Keyword arguments:
org_id -- 操作数据所属的组织机构id
user -- 当前用户信息
Return: 
True: 有权限
False: 无权限
"""


def check_data_permission(org_id, user: models.SystemUserRead, session: SessionDep = Session(engine)):
    # 查询全部组织机构
    orgs = session.exec(select(models.SystemOrg)).all()

    if org_id:
        # 获取数据可以访问的组织机构id列表
        org_ids = get_node_ids(orgs, org_id)

        # 校验当前用户是否在数据可以访问的组织机构id列表中
        if user.org_id not in org_ids:
            return False
    return True


"""将菜单id为key，菜单信息为value的字典

Keyword arguments:
org_list_id -- 组织机构id列表
db -- 数据库会话
Return: items -- 组织机构信息字典
"""

def build_org_dict(org_list_id, db):
    # 初始化组合角色拥有的菜单信息
    org_list = []

    # 根据拥有权限的id组合成树状​结构
    for i in org_list_id:
        org_info = org.get_org(i, db=db)[0]
        menu_obj = {
            'id': org_info.id,
            'name': org_info.name,
            'code': org_info.code,
            'parent_id': org_info.parent_id,
            'order': org_info.order,
            'is_active': org_info.is_active,
            'notes': org_info.notes,
        }
        org_list.append(menu_obj)

    # 构建树状结构
    items = build_tree_recursive(org_list)

    return items


"""获取树中的所有节点id

Keyword arguments:
items --  树状结构
Return: node_id -- 所有节点id
"""
def get_all_node_id(items):
    node_id = []
    if len(items) != 0:
        for i in items:
            if 'id' in i:
                node_id.append(i['id'])
                if 'children' in i:
                    node_id.extend(get_all_node_id(i['children']))
    return node_id


"""生成版本号

Keyword arguments:
none
Return: version_number -- 生成的版本号
"""

def generate_version_number():
    # 生成当前时间戳
    current_timestamp = time.time()
    readable_date = datetime.datetime.fromtimestamp(
        current_timestamp).strftime('%Y-%m-%d %H:%M:%S')

    # 生成版本号
    version_number = readable_date.replace(
        "-", "").replace(" ", "").replace(":", "") + str(random.randint(100, 9999))

    return version_number


# 存储已生成的字符串，确保唯一性
existing_strings = set()


""" 随机唯一短字符串

Keyword arguments:
length --  生成字符串的长度，默认为8
Return: unique_string -- 生成的唯一随机字符串
"""
def generate_unique_string(length=8):
    """生成一个唯一的随机字符串。

    :param length: 生成字符串的长度，默认为8。
    :return: 生成的唯一随机字符串。
    """
    current_time = str(time.time())
    hash_object = hashlib.sha256(current_time.encode())
    return hash_object.hexdigest()[:length]
